﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Globalization;
using System.Windows.Input;

namespace Base.ModuleBase.Attachs
{
    public class DatePickerAttach
    {
        protected static log4net.ILog _logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public static object GetWatermark(DependencyObject obj)
        {
            return obj.GetValue(WatermarkProperty);
        }

        public static void SetWatermark(DependencyObject obj, object value)
        {
            obj.SetValue(WatermarkProperty, value);
        }

        // Using a DependencyProperty as the backing store for Watermark.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WatermarkProperty =
            DependencyProperty.RegisterAttached("Watermark", typeof(object), typeof(DatePickerAttach),
                new FrameworkPropertyMetadata(null,
                    new PropertyChangedCallback(OnWatermarkChanged)));

        private static void OnWatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var datePicker = d as DatePicker;
            if (datePicker == null)
                return;
            if (datePicker.IsLoaded)
            {
                SetWatermarkInternal(datePicker, e.NewValue);
            }
            else
            {
                RoutedEventHandler loadedHandler = null;
                loadedHandler = delegate
                {
                    datePicker.Loaded -= loadedHandler;
                    SetWatermarkInternal(datePicker, e.NewValue);
                };
                datePicker.Loaded += loadedHandler;
            }
        }
        private static void SetWatermarkInternal(DatePicker d, object value)
        {
            var textBox = d.Template.FindName("PART_TextBox", d) as Control;
            if (textBox != null)
            {
                var watermarkControl = textBox.Template.FindName("PART_Watermark", textBox) as ContentControl;
                if (watermarkControl != null)
                    watermarkControl.Content = value;
            }
        }

        public static readonly DependencyProperty EnableFastInputProperty =
         DependencyProperty.RegisterAttached("EnableFastInput", typeof(bool), typeof(DatePickerAttach),
                new FrameworkPropertyMetadata(false,
                new PropertyChangedCallback(OnEnableFastInputChanged)));

        public static bool GetEnableFastInput(DependencyObject d)
        {
            return (bool)d.GetValue(EnableFastInputProperty);
        }

        public static void SetEnableFastInput(DependencyObject d, bool value)
        {
            d.SetValue(EnableFastInputProperty, value);
        }

        private static void OnEnableFastInputChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var datePicker = d as DatePicker;
            if (datePicker != null)
            {
                if ((bool)e.NewValue)
                {
                    datePicker.DateValidationError += DatePickerOnDateValidationError;
                    //datePicker.GotFocus += datePicker_GotFocus;
                    //datePicker.LostFocus += datePicker_LostFocus;
                    //datePicker.PreviewMouseDown += datePicker_PreviewMouseDown;

                    //var textBox = datePicker.Template.FindName("PART_TextBox", datePicker) as TextBox;
                    //if (textBox != null)
                    //{
                    //    textBox.PreviewKeyDown += textBox_PreviewKeyDown;
                    //}                    
                }
                else
                {
                    datePicker.DateValidationError -= DatePickerOnDateValidationError;
                    //datePicker.GotFocus -= datePicker_GotFocus;
                    //datePicker.LostFocus -= datePicker_LostFocus;
                    //datePicker.PreviewMouseDown -= datePicker_PreviewMouseDown;                    
                }
            }
        }

        static void textBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Up || e.Key == Key.Down)
            {
                TextBox textBox = sender as TextBox;

                int direction = e.Key == Key.Up ? 1 : -1;
                string currentDateText = textBox.Text;

                DateTime result;
                if (!DateTime.TryParse(textBox.Text, out result))
                    return;

                char delimeter = ' ';

                //switch (this.SelectedDateFormat)
                //{
                //    case DatePickerFormat.Short: // dd/mm/yyyy
                //        delimeter = '/';
                //        break;
                //    case DatePickerFormat.Long:  // day month  year
                //        delimeter = ' ';
                //        break;
                //}

                //int index = 3;
                //bool foundIt = false;
                //for (int i = Text.Length - 1; i >= 0; i--)
                //{
                //    if (Text[i] == delimeter)
                //    {
                //        --index;
                //        if (textBox.CaretIndex > i)
                //        {
                //            foundIt = true;
                //            break;
                //        }
                //    }
                //}

                //if (!foundIt)
                //    index = 0;


                //switch (index)
                //{
                //    case 0: // Day
                //        result = result.AddDays(direction);
                //        break;
                //    case 1: // Month
                //        result = result.AddMonths(direction);
                //        break;
                //    case 2: // Year
                //        result = result.AddYears(direction);
                //        break;
                //}

                //while (this.BlackoutDates.Contains(result))
                //{
                //    result = result.AddDays(direction);
                //}


                //DateTimeFormatInfo dtfi = DateTimeHelper.GetCurrentDateFormat();
                //switch (this.SelectedDateFormat)
                //{
                //    case DatePickerFormat.Short:
                //        this.Text = string.Format(CultureInfo.CurrentCulture,
                //                    result.ToString(dtfi.ShortDatePattern, dtfi));
                //        //this.Text =  result.ToShortDateString();
                //        break;
                //    case DatePickerFormat.Long:
                //        this.Text = string.Format(CultureInfo.CurrentCulture,
                //                    result.ToString(dtfi.LongDatePattern, dtfi));
                //        //this.Text = result.ToLongDateString();
                //        break;
                //}

                //switch (index)
                //{
                //    case 1:
                //        textBox.CaretIndex = Text.IndexOf(delimeter) + 1;
                //        break;
                //    case 2:
                //        textBox.CaretIndex = Text.LastIndexOf(delimeter) + 1;
                //        break;
                //}
            }
        }

        static void datePicker_LostFocus(object sender, RoutedEventArgs e)
        {
            var datePicker = sender as DatePicker;
            if (datePicker != null)
            {
                var textBox = datePicker.Template.FindName("PART_TextBox", datePicker) as TextBox;
                if (textBox != null)
                {
                    textBox.PreviewMouseDown += datePicker_PreviewMouseDown;
                }
            }
        }

        static void datePicker_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            var datePicker = sender as DatePicker;
            if (datePicker != null)
            {
                var textBox = datePicker.Template.FindName("PART_TextBox", datePicker) as TextBox;
                if (textBox != null)
                {
                    textBox.Focus();
                }
            }

            e.Handled = true;
        }

        private static void DatePickerOnDateValidationError(object sender, DatePickerDateValidationErrorEventArgs e)
        {
            var datePicker = sender as DatePicker;
            if (datePicker != null)
            {
                var text = e.Text;
                DateTime dateTime;

                //var dateFormat = GetWatermark(datePicker).ToString();
                var dateFormat = "";
                object objectWatermark = GetWatermark(datePicker);
                if (objectWatermark != null)
                {
                    dateFormat = objectWatermark.ToString();
                }

                //if (string.IsNullOrEmpty(dateFormat))
                //{
                //    dateFormat = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
                //}
                if (dateFormat.Contains(";"))
                {
                    var tempInfos = dateFormat.Split(';');
                    var tempDateFormatInfos = tempInfos.Select(s => s.Trim()).ToArray();
                    if (DateTime.TryParseExact(text, tempDateFormatInfos, CultureInfo.CurrentUICulture, DateTimeStyles.None, out dateTime))
                    {
                        try
                        {
                            datePicker.SelectedDate = dateTime;
                        }
                        catch (Exception ex)
                        {
                            _logger.Error($"[Exception]->{ex.Message},{ex.StackTrace}");

                            datePicker.SelectedDate = DateTime.Now.Date;
                        }
                    }
                }
                else
                {
                    if (DateTime.TryParseExact(text, dateFormat, CultureInfo.CurrentUICulture, DateTimeStyles.None, out dateTime))
                    {
                        try
                        {
                            datePicker.SelectedDate = dateTime;
                        }
                        catch (Exception ex)
                        {
                            _logger.Error($"[Exception]->{ex.Message},{ex.StackTrace}");

                            datePicker.SelectedDate = DateTime.Now.Date;
                        }
                    }
                }
            }
        }

        static void datePicker_GotFocus(object sender, RoutedEventArgs e)
        {
            var datePicker = sender as DatePicker;
            if (datePicker != null)
            {
                var textBox = datePicker.Template.FindName("PART_TextBox", datePicker) as TextBox;
                if (textBox != null)
                {
                    textBox.SelectAll();
                    textBox.PreviewMouseDown -= datePicker_PreviewMouseDown;
                }
            }
        }
    }
}
